package online.heycm.platform.lock;

import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

/**
 * 锁操作实现
 *
 * @author heycm
 * @since 2023/1/27 15:38
 */
@Slf4j
public class RedisLockImpl implements RedisLock {

    private final ThreadLocal<RLock> locks = new ThreadLocal<>();

    private final RedissonClient redissonClient;

    public RedisLockImpl(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    @Override
    public boolean lock(String key, long maxWait, long leaseTime) {
        final RLock rLock = redissonClient.getLock(key);
        locks.set(rLock);
        try {
            final boolean result = rLock.tryLock(maxWait, leaseTime, TimeUnit.MILLISECONDS);
            log.info("DistributedLock [{}] get lock {}.", key, result ? "success" : "fail");
            return result;
        } catch (InterruptedException e) {
            log.info("DistributedLock [{}] get lock error.", key, e);
        }
        return false;
    }

    @Override
    public void unlock() {
        final RLock rLock = locks.get();
        if (rLock != null && rLock.isLocked() && rLock.isHeldByCurrentThread()) {
            rLock.unlock();
            locks.remove();
            log.info("DistributedLock [{}] release lock.", rLock.getName());
            return;
        }
        log.warn("DistributedLock lock is invalid, not need to release.");
    }
}
